﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using System.IO;
public static class Loger
{
    //Duger总开关
    public static bool IsDebuger = true;

    public static bool IsInfo = true;
    public static bool IsWarring = true;
    public static bool IsError = true;
    public static bool IsSpecial = true;

    //信息是否保存到文件
    public static bool IsInfoSave = false;
    public static bool IsWarringSave = false;
    public static bool IsErrorSave = true;
    public static bool IsSpecialSave = false;

    public static List<Log> logs = new List<Log>();
    //日志文件路径
    public static string LogFileDir = Application.persistentDataPath + "/DebugerLog/";
    public static string Prefix = ">> ";


    public static void Info(this object obj, string message)
    {
        if (!IsDebuger)
            return;
        if (!IsInfo)
            return;
        string str = DateTime.Now.ToString("HH:mm:ss") + "  [Info]  " + obj.GetType().Name + Prefix + message;
        SetDebugLog(str, LogType.Log, IsInfoSave);
    }


    public static void Info(this object obj, string format, params object[] args)
    {
        if (!IsDebuger)
            return;
        if (!IsInfo)
            return;
        string message = string.Format(format, args);
        string str = DateTime.Now.ToString("HH:mm:ss") + "  [Info]  " + obj.GetType().Name + Prefix + message;
        SetDebugLog(str, LogType.Log, IsInfoSave);
    }


    public static void Info(string tag, string message)
    {
        if (!IsDebuger)
            return;
        if (!IsInfo)
            return;
        string str = DateTime.Now.ToString("HH:mm:ss") + "  [Info]  " + tag + Prefix + message;
        SetDebugLog(str, LogType.Log, IsInfoSave);
    }

    public static void Info(string tag, string format, params object[] args)
    {
        if (!IsDebuger)
            return;
        if (!IsInfo)
            return;
        string message = string.Format(format, args);
        string str = DateTime.Now.ToString("HH:mm:ss") + "  [Info]  " + tag + Prefix + message;
        SetDebugLog(str, LogType.Log, IsInfoSave);
    }

    public static void Warring(this object obj, string message)
    {
        if (!IsDebuger || !IsWarring)
            return;
        string str = DateTime.Now.ToString("HH:mm:ss") + "  [Warring]  " + obj.GetType().Name + Prefix + message;
        SetDebugLog(str, LogType.Warning, IsWarringSave);
    }

    public static void Warring(this object obj, string format, params object[] args)
    {
        if (!IsDebuger || !IsWarring)
            return;
        string message = string.Format(format, args);
        string str = DateTime.Now.ToString("HH:mm:ss") + "  [Warring]  " + obj.GetType().Name + Prefix + message;
        SetDebugLog(str, LogType.Warning, IsWarringSave);
    }


    public static void Warring(string tag, string message)
    {
        if (!IsDebuger || !IsWarring)
            return;
        string str = DateTime.Now.ToString("HH:mm:ss") + "  [Warring]  " + tag + Prefix + message;
        SetDebugLog(str, LogType.Warning, IsWarringSave);
    }

    public static void Warring(string tag, string format, params object[] args)
    {
        if (!IsDebuger || !IsWarring)
            return;
        string message = string.Format(format, args);
        string str = DateTime.Now.ToString("HH:mm:ss") + "  [Warring]  " + tag + Prefix + message;
        SetDebugLog(str, LogType.Warning, IsWarringSave);
    }

    public static void Special(this object obj, string message)
    {
        if (!IsDebuger || !IsSpecial)
            return;
        string str = DateTime.Now.ToString("HH:mm:ss") + "  [Special]  " + obj.GetType().Name + Prefix + message;
        SetDebugLog(str, LogType.Assert, IsSpecialSave);
    }

    public static void Special(this object obj, string format, params object[] args)
    {
        if (!IsDebuger || !IsSpecial)
            return;
        string message = string.Format(format, args);
        string str = DateTime.Now.ToString("HH:mm:ss") + "  [Special]  " + obj.GetType().Name + Prefix + message;
        SetDebugLog(str, LogType.Assert, IsSpecialSave);
    }

    public static void Special(string tag, string message)
    {
        if (!IsDebuger || !IsSpecial)
            return;
        string str = DateTime.Now.ToString("HH:mm:ss") + "  [Special]  " + tag + Prefix + message;
        SetDebugLog(str, LogType.Assert, IsSpecialSave);
    }

    public static void Special(string tag, string format, params object[] args)
    {
        if (!IsDebuger || !IsSpecial)
            return;
        string message = string.Format(format, args);
        string str = DateTime.Now.ToString("HH:mm:ss") + "  [Special]  " + tag + Prefix + message;
        SetDebugLog(str, LogType.Assert, IsSpecialSave);
    }

    public static void Error(this object obj, string message)
    {
        if (!IsDebuger || !IsError)
            return;
        string str = DateTime.Now.ToString("HH:mm:ss") + "  [Error]  " + obj.GetType().Name + Prefix + message;
        SetDebugLog(str, LogType.Error, IsErrorSave);
    }

    public static void Error(this object obj, string format, params object[] args)
    {
        if (!IsDebuger || !IsError)
            return;
        string message = string.Format(format, args);
        string str = DateTime.Now.ToString("HH:mm:ss") + "  [Error]  " + obj.GetType().Name + Prefix + message;
        SetDebugLog(str, LogType.Error, IsErrorSave);
    }

    public static void Error(string tag, string message)
    {
        if (!IsDebuger || !IsError)
            return;
        string str = DateTime.Now.ToString("HH:mm:ss") + "  [Error]  " + tag + Prefix + message;
        SetDebugLog(str, LogType.Error, IsErrorSave);
    }

    public static void Error(string tag, string format, params object[] args)
    {
        if (!IsDebuger || !IsError)
            return;
        string message = string.Format(format, args);
        string str = DateTime.Now.ToString("HH:mm:ss") + "  [Error]  " + tag + Prefix + message;
        SetDebugLog(str, LogType.Error, IsErrorSave);
    }

    private static void SetDebugLog(string message, LogType type, bool isSave)
    {
        if (!IsDebuger)
            return;
        string color = _GetLogModeColor(type);
        Debug.Log("<color=" + color + ">" + message + "</color>");
        if (isSave)
        {
            //保存
            WriteLogForFile(message);
        }
    }



    /// <summary>
    /// log输出颜色
    /// </summary>
    /// <param name="level"></param>
    /// <returns></returns>
    private static string _GetLogModeColor(LogType level)
    {
        string nColor = "#FFFFFFFF";

        switch (level)
        {
            case LogType.Assert:
                nColor = "##22FF4E";//绿色
                break;

            case LogType.Log:
                nColor = "#FFFFFFFF";//白色
                break;

            case LogType.Warning:
                nColor = "#F9F93A";//黄色
                break;

            case LogType.Error:
                nColor = "#FF0000";//红色
                break;

            case LogType.Exception:
                nColor = "#FF0000";//红色
                break;
        }
        return nColor;
    }


    /// <summary>
    /// 写入日志信息
    /// </summary>
    public static void WriteLogForFile(string message)
    {
        string fileName = LogFileDir + "log.txt";
        try
        {
            message = DateTime.Now.ToString("yyyy-MM-dd") + "  " + message + "\n";
            if (!Directory.Exists(LogFileDir))
            {
                Directory.CreateDirectory(LogFileDir);
            }
            if (!File.Exists(fileName))
            {
                FileStream stream = new FileStream(fileName, FileMode.Create);
                byte[] data = Encoding.UTF8.GetBytes(message.ToString());
                stream.Write(data, 0, data.Length);
                stream.Flush();
                stream.Close();
            }
            else
            {
                FileInfo fileInfo = new FileInfo(fileName);
                double n = System.Math.Ceiling(fileInfo.Length / 1024.0);
                if (n > 210)
                {
                    //文件大于210k时，只保留源文件最后的1/5大小的数据，
                    string[] strs = File.ReadAllLines(fileName);
                    StringBuilder sb = new StringBuilder();
                    //Debug.Log("legth:" + strs.Length + ",length2:" + strs.Length / 5);
                    int startIndex = (strs.Length / 5) * 4;
                    for (int i = startIndex; i < strs.Length; i++)
                    {
                        sb.AppendLine(strs[i]);
                    }
                    sb.AppendLine(message);
                    FileStream stream = new FileStream(fileName, FileMode.Create);
                    byte[] data = Encoding.UTF8.GetBytes(sb.ToString());
                    stream.Write(data, 0, data.Length);
                    stream.Flush();
                    stream.Close();
                }
                else
                {
                    FileStream fs = null;
                    Encoding encoder = Encoding.UTF8;
                    byte[] bytes = encoder.GetBytes(message);
                    try
                    {
                        fs = File.OpenWrite(fileName);
                        fs.Position = fs.Length;
                        fs.Write(bytes, 0, bytes.Length);
                    }
                    catch (Exception ex)
                    {
                        Debug.Log("ex:" + ex.ToString());
                    }
                    finally
                    {
                        fs.Close();
                    }
                }
            }
            Debug.Log("filePath:" + fileName);
            //using (FileStream fs = new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.Write))
            //{
            //    using (StreamWriter sw = new StreamWriter(fs))
            //    {

            //        //sw.BaseStream.Seek(0, SeekOrigin.End);
            //        //sw.w
            //        sw.WriteLine(message);
            //        sw.Flush();
            //    }
            //}

        }
        catch (Exception ex)
        {
            Debug.Log("ex:" + ex.ToString());
        }

    }
}

public class Log
{
    public string message;
    public string tag;
    public LogType type;
}
